import 'dart:convert' show json;

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:mahjong/const/MahjongConst.dart';
import 'package:mahjong/entity/UserTask.dart';
import 'package:mahjong/entity/UserTouchBar.dart';
import 'package:mahjong/entity/user/MahjongUserInfo.dart';
import 'package:mahjong/entity/rule/MahjongRule.dart';
import 'package:mahjong/util/CustomerDialog.dart';
import 'package:mahjong/widget/CustomDialog.dart';

T asT<T>(dynamic value) {
  if (value is T) {
    return value;
  }
  return null;
}

class MahjongInfoEntity with ChangeNotifier {
  MahjongInfoEntity(
      {this.roomType,
      this.code,
      this.bankerIndex,
      this.currentExportUserId,
      this.currentExportCard,
      this.licensingCard,
      this.currentBar,
      this.gamesNumber,
      this.gamesCurrentNumber,
      this.createDate,
      this.gameStartDate,
      this.gameEndDate,
      this.allCard,
      this.exchangeValue,
      this.state = 0,
      this.currentUserTouchBarCards,
      this.userCards,
      this.userExchangeCards,
      this.userInCards,
      this.userExportCards,
      this.billClearingInfo,
      this.allCardCount,
      this.rule,
      this.allUserMap,
      this.allUser,
      this.showBillHistory: false});
  void nextGame(bool nextGame) {
    this.showBillHistory = false;
    notifyListeners();
  }

  void clean() {
    this.state = 0;
    this.roomType = null;
    this.code = null;
    this.bankerIndex = null;
    this.currentExportUserId = null;
    this.currentExportCard = null;
    this.licensingCard = null;
    this.currentBar = null;
    this.gamesNumber = null;
    this.gamesCurrentNumber = null;
    this.createDate = null;
    this.gameStartDate = null;
    this.gameEndDate = null;
    this.allCard = null;
    this.exchangeValue = null;
    this.currentUserTouchBarCards = null;
    this.userCards = null;
    this.userExchangeCards = null;
    this.userInCards = null;
    this.userExportCards = null;
    this.billClearingInfo = null;
    this.allCardCount = null;
    this.rule = null;
    this.allUserMap = null;
    this.allUser = null;
    this.showBillHistory = false;
  }

  void userLicensingCard() {
    this.allCardCount--;
    if (this.allCardCount == 3) {
      CustomerDialog.showText("游戏进入后四",
          bottomColor: Colors.orange, textColor: Colors.red);
    }
    notifyListeners();
  }

  void updateInfo(MahjongInfoEntity roomInfo) {
    this.state = roomInfo.state;
    this.roomType = roomInfo.roomType;
    this.gamesCurrentNumber = roomInfo.gamesCurrentNumber;
    this.allCardCount = roomInfo.allCardCount;
    this.bankerIndex = roomInfo.bankerIndex;
    this.gamesNumber = roomInfo.gamesNumber;
    this.billClearingInfo = roomInfo.billClearingInfo;
    this.rule = roomInfo.rule;
    this.licensingCard = roomInfo.licensingCard;
    this.exchangeValue = roomInfo.exchangeValue;
    this.code = roomInfo.code;
    this.allUserMap = roomInfo.allUserMap;
    this.allUser = roomInfo.allUser;
    this.gameEndDate = roomInfo.gameEndDate;
    if (this.state == RoomState.BILL_CLEARING || this.state == RoomState.OVER) {
      this.showBillHistory = true;
    } else {
      this.showBillHistory = false;
    }
    notifyListeners();
  }

  factory MahjongInfoEntity.fromJson(Map<String, dynamic> jsonRes) {
    if (jsonRes == null) {
      return null;
    }
    final List<BillClearingInfo> billClearingInfo =
        jsonRes['billClearingInfo'] is List ? <BillClearingInfo>[] : null;
    if (billClearingInfo != null) {
      for (final dynamic item in jsonRes['billClearingInfo']) {
        if (item != null) {
          billClearingInfo
              .add(BillClearingInfo.fromJson(asT<Map<String, dynamic>>(item)));
        }
      }
    }

    Map<String, MahjongUserInfo> allUserMaps;
    List<MahjongUserInfo> allUser = [];
    var alluserInfoData = jsonRes['allUserInfo'];
    if (alluserInfoData != null && alluserInfoData is Map) {
      allUserMaps = {};
      var allUserTemp = Map.castFrom(jsonRes["allUserInfo"]);
      allUserTemp.forEach((key, value) {
        var userInfo = MahjongUserInfo.fromJson(Map.castFrom(value));
        allUser.add(userInfo);
        allUserMaps[key] = userInfo;
      });
    }

    return MahjongInfoEntity(
      roomType: asT<String>(jsonRes['roomType']),
      code: asT<Object>(jsonRes['code']),
      bankerIndex: asT<Object>(jsonRes['bankerIndex']),
      currentExportUserId: asT<Object>(jsonRes['currentExportUserId']),
      currentExportCard: asT<Object>(jsonRes['currentExportCard']),
      licensingCard: asT<Object>(jsonRes['licensingCard']),
      currentBar: asT<bool>(jsonRes['currentBar']),
      gamesNumber: asT<int>(jsonRes['gamesNumber']),
      gamesCurrentNumber: asT<int>(jsonRes['gamesCurrentNumber']),
      createDate: asT<Object>(jsonRes['createDate']),
      gameStartDate: asT<Object>(jsonRes['gameStartDate']),
      gameEndDate: asT<String>(jsonRes['gameEndDate']),
      allCard: asT<Object>(jsonRes['allCard']),
      exchangeValue: asT<int>(jsonRes['exchangeValue']),
      state: asT<int>(jsonRes['state']),
      allUserMap: allUserMaps,
      allUser: allUser,
      currentUserTouchBarCards:
          asT<Object>(jsonRes['currentUserTouchBarCards']),
      userCards: asT<Object>(jsonRes['userCards']),
      userExchangeCards: asT<Object>(jsonRes['userExchangeCards']),
      userInCards: asT<Object>(jsonRes['userInCards']),
      userExportCards: asT<Object>(jsonRes['userExportCards']),
      billClearingInfo: billClearingInfo,
      allCardCount: asT<int>(jsonRes['allCardCount']),
      rule: MahjongRule.fromJson(jsonRes['rule']),
    );
  }

  String roomType;
  Object code;
  Object bankerIndex;
  Object currentExportUserId;
  Object currentExportCard;
  Object licensingCard;
  bool currentBar;
  int gamesNumber;
  int gamesCurrentNumber;
  Object createDate;
  Object gameStartDate;
  String gameEndDate;
  Object allCard;
  int exchangeValue;
  int state;
  Object currentUserTouchBarCards;
  Object userCards;
  Object userExchangeCards;
  Object userInCards;
  Object userExportCards;
  List<BillClearingInfo> billClearingInfo;
  int allCardCount;
  MahjongRule rule;
  Map<String, MahjongUserInfo> allUserMap;
  List<MahjongUserInfo> allUser;
  bool showBillHistory;

  Map<String, dynamic> toJson() => <String, dynamic>{
        'roomType': roomType,
        'code': code,
        'bankerIndex': bankerIndex,
        'currentExportUserId': currentExportUserId,
        'currentExportCard': currentExportCard,
        'licensingCard': licensingCard,
        'currentBar': currentBar,
        'gamesNumber': gamesNumber,
        'gamesCurrentNumber': gamesCurrentNumber,
        'createDate': createDate,
        'gameStartDate': gameStartDate,
        'gameEndDate': gameEndDate,
        'allCard': allCard,
        'exchangeValue': exchangeValue,
        'state': state,
        'currentUserTouchBarCards': currentUserTouchBarCards,
        'userCards': userCards,
        'userExchangeCards': userExchangeCards,
        'userInCards': userInCards,
        'userExportCards': userExportCards,
        'billClearingInfo': billClearingInfo,
        'allCardCount': allCardCount,
        'rule': rule,
        'allUserInfo': allUserMap,
        'allUser': allUser
      };

  @override
  String toString() {
    return json.encode(this);
  }
}

class BillClearingInfo {
  BillClearingInfo({
    this.userInfo,
    this.userWinSeq,
    this.fraction,
    this.fractionResources,
    this.winState,
    this.userCards,
    this.huCard,
    this.cardTouchBars,
  });

  factory BillClearingInfo.fromJson(Map<String, dynamic> jsonRes) {
    if (jsonRes == null) {
      return null;
    }
    final List<String> fractionResources =
        jsonRes['fractionResources'] is List ? <String>[] : null;
    if (fractionResources != null) {
      for (final dynamic item in jsonRes['fractionResources']) {
        if (item != null) {
          fractionResources.add(asT<String>(item));
        }
      }
    }

    final List<int> userCards = jsonRes['userCards'] is List ? <int>[] : null;
    if (userCards != null) {
      for (final dynamic item in jsonRes['userCards']) {
        if (item != null) {
          userCards.add(asT<int>(item));
        }
      }
    }

    final List<UserTouchBar> cardTouchBars =
        jsonRes['cardTouchBars'] is List ? <UserTouchBar>[] : null;
    if (cardTouchBars != null) {
      for (final dynamic item in jsonRes['cardTouchBars']) {
        if (item != null) {
          cardTouchBars.add(UserTouchBar.fromJson(item));
        }
      }
    }

    return BillClearingInfo(
        userInfo: MahjongUserInfo.fromJson(
            asT<Map<String, dynamic>>(jsonRes['userInfo'])),
        userWinSeq: asT<int>(jsonRes['userWinSeq']),
        fraction: asT<int>(jsonRes['fraction']),
        winState: asT<bool>(jsonRes['winState']),
        fractionResources: fractionResources,
        userCards: userCards,
        huCard: asT<int>(jsonRes['huCard']),
        cardTouchBars: cardTouchBars);
  }

  MahjongUserInfo userInfo;
  int userWinSeq;
  int fraction;
  bool winState;
  List<String> fractionResources;
  List<int> userCards;
  int huCard;
  List<UserTouchBar> cardTouchBars;

  Map<String, dynamic> toJson() => <String, dynamic>{
        'userInfo': userInfo,
        'userWinSeq': userWinSeq,
        'winState': winState,
        'fraction': fraction,
        'fractionResources': fractionResources,
        'userCards': userCards,
        "huCard": huCard,
        "cardTouchBars": cardTouchBars
      };

  @override
  String toString() {
    return json.encode(this);
  }
}
